
package com.platform.modules.mall.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.*;
import com.platform.modules.mall.dao.MallUserCardDao;
import com.platform.modules.mall.entity.MallCardSnEntity;
import com.platform.modules.mall.entity.MallGoodsEntity;
import com.platform.modules.mall.entity.MallUserCardEntity;
import com.platform.modules.mall.entity.MallUserEntity;
import com.platform.modules.mall.entity.dto.CardAssignDto;
import com.platform.modules.mall.service.MallCardSnService;
import com.platform.modules.mall.service.MallGoodsService;
import com.platform.modules.mall.service.MallUserCardService;
import com.platform.modules.mall.service.MallUserService;
import com.platform.modules.phone.entity.dto.PhoneTopUpDto;
import com.platform.modules.phone.service.PhoneTopUpService;
import com.platform.modules.sys.service.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 用户卡卷Service实现类
 *
 * @author tech
 * @date 2020-08-04 22:52:36
 */
@Service("mallUserCardService")
public class MallUserCardServiceImpl extends ServiceImpl<MallUserCardDao, MallUserCardEntity> implements MallUserCardService {
    @Autowired
    @Lazy
    MallCardSnService cardSnService;
    @Autowired
    MallGoodsService goodsService;
    @Autowired
    MallUserService userService;
    @Autowired
    SendCoupon sendCoupon;

    @Autowired
    private PhoneTopUpService phoneTopUpService;

    @Autowired
    private SysConfigService sysConfigService;

    // 微信立减金类型
    Integer weixinCoupon = 98;

    // 微信立减金类型
    Integer phoneUp = 97;
    @Override
    public List<MallUserCardEntity> queryAll(Map<String, Object> params) {
        return baseMapper.queryAll(params);
    }

    @Override
    public Page queryPage(Map<String, Object> params) {
        //排序
        params.put("sidx", "T.id");
        params.put("asc", false);
        Page<MallUserCardEntity> page = new Query<MallUserCardEntity>(params).getPage();
        return page.setRecords(baseMapper.selectMallUserCardPage(page, params));
    }

    @Override
    public Page<Map<String, Object>> selectUserCardPage(Map<String, Object> params) {
        //排序
        params.put("sidx", "T.EXPIRE_TIME");
        params.put("asc", true);
        Page<Map<String, Object>> page = new Query<Map<String, Object>>(params).getPage();
        return page.setRecords(baseMapper.selectUserCardPage(page, params));
    }

    @Override
    public Page writeOffList(Map<String, Object> params) {
        //排序
        params.put("sidx", "T.id");
        params.put("asc", false);
        Page<Map<String, Object>> page = new Query<Map<String, Object>>(params).getPage();
        return page.setRecords(baseMapper.writeOffList(page, params));
    }

    @Override
    public MallUserCardEntity getOne4Update(String id) {
        return baseMapper.getOne4Update(id);
    }

    @Override
    public boolean updateByStatus(MallUserCardEntity userCard) {
        return baseMapper.updateByStatus(userCard);
    }

    @Override
    public List<MallUserCardEntity> selectUserCard(String UserId) {
        return baseMapper.selectUserCard(UserId);
    }

    /**
     * 根据用户id和卡券id发放卡券
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public boolean cardAssingn(CardAssignDto dto) {
        synchronized (dto.getGoodsId().intern()) {
            int userSize = dto.getUserId().size();
            // 获取卡券
            String orderId = "";
            MallUserCardEntity userCardEntity;
            List<MallUserCardEntity> userCardEntityList = new ArrayList<>(userSize);
            MallGoodsEntity goodsEntity = goodsService.getById(dto.getGoodsId());
            BigDecimal marketPrice = goodsEntity.getMarketPrice();
            goodsEntity.setGoodsNumber(goodsEntity.getGoodsNumber() - userSize);
            if (goodsEntity.getGoodsNumber() < 0) {
                throw new BusinessException("卡券数量不足");
            }
            List<MallCardSnEntity> cardSnEntityList = cardSnService.getCardSn(dto.getGoodsId(), userSize);
            if (cardSnEntityList == null || cardSnEntityList.size() != userSize) {
                throw new BusinessException("卡券数量不足");
            }
            goodsService.update(goodsEntity);
            MallUserEntity userEntity = null;
            JSONObject js = new JSONObject();
            for (String userId : dto.getUserId()) {
                userCardEntity = new MallUserCardEntity();
                userCardEntity.setCardId(dto.getGoodsId());
                userCardEntity.setExpireTime(DateUtils.addDateDays(new Date(), goodsEntity.getExpireDay()));
                userCardEntity.setUserId(userId);
                userCardEntity.setMarketPrice(goodsEntity.getMarketPrice());
                userCardEntity.setRetailPrice(goodsEntity.getMarketPrice());
                userCardEntity.setAddTime(new Date());
                userCardEntity.setPayType(dto.getPayType());
                for (MallCardSnEntity entity : cardSnEntityList) {
                    if (weixinCoupon - entity.getType() == 0) {
                        userEntity = userService.getById(userId);
                        String[] stockIds = entity.getCardSn().split(",");
                        for (String stockId : stockIds) {
                            js.put("openid", userEntity.getOpenId());
                            js.put("stockId", stockId);
                            // 发放微信立减金
                            try {
                                String proxyConfig = sysConfigService.getValue(Constant.SYS_PROXY_SERVER);
                                JSONObject proxyConfigJs = JSONObject.parseObject(proxyConfig);
                                String proxyServerIp = proxyConfigJs.getString("proxyServerIp");
                                Integer proxyPort = proxyConfigJs.getInteger("proxyPort");
                                sendCoupon.sendCouponV3(js,proxyServerIp,proxyPort);
//                                sendCoupon.sendCouponV3(js);
                            } catch (Exception e) {
                                log.error("立减金发送失败：" + userEntity.getMobile() + "，snId：" + entity.getId());
                                log.error("立减金发送失败：", e);
                                continue;
                            }
                        }
                    }
                    if(phoneUp - entity.getType() == 0){
                        // 手机充值
                        // 构建话费充值数据
                        PhoneTopUpDto pdto = new PhoneTopUpDto();
                        // 生成并设置话费充值的订单号
                        pdto.setOrderId(orderId = StringUtils.generateOrderNumber());
                        pdto.setCartNo(Long.valueOf(dto.getCartNo()));
                        // 填写充值金额  元为单位
                        pdto.setTopUpMoney(marketPrice);
                        pdto.setUserId(userId);
                        phoneTopUpService.topUp(pdto);
                    }
                    userCardEntity.setType(entity.getType());
                    userCardEntity.setCardSn(entity.getCardSn());
                    userCardEntityList.add(userCardEntity);
                    entity.setStatus(Byte.valueOf("1"));
                    cardSnService.updateById(entity);
                    break;
                }
                // 每次取第一个
                cardSnEntityList.remove(0);
            }
            this.saveBatch(userCardEntityList, userSize);

            return true;
        }
    }

    @Override
    public void expireCard() {
        //判断日期减一,因为有效期就存了日期查询会导致当天应该在23点失效的在0点就失效了
        List<MallUserCardEntity> userCardEntitys = this.list(new QueryWrapper<MallUserCardEntity>()
                .lt("EXPIRE_TIME", DateUtils.addDateDays(new Date(), -1)).in("status", 0, 1));
        if (userCardEntitys != null && userCardEntitys.size() > 0) {
            // 设置用户卡券过期
            userCardEntitys.stream().forEach(card -> {
                card.setStatus(2);
            });
            this.updateBatchById(userCardEntitys);
        }
    }

    @Override
    public boolean add(MallUserCardEntity mallUserCard) {
        return this.save(mallUserCard);
    }

    @Override
    public boolean update(MallUserCardEntity mallUserCard) {
        return this.updateById(mallUserCard);
    }

    @Override
    public boolean delete(String id) {
        return this.removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatch(String[] ids) {
        return this.removeByIds(Arrays.asList(ids));
    }

}
